
import { Path } from 'three';

import earcut from 'earcut';
import { HoleMeta, CreateMeta } from '../../meta/MetaClass';
import AluGeoUtil from '@/model/geometry/utils/AluGeoUtil';
import { polygon } from '@turf/helpers';
import difference from '@turf/difference';
import AModelFmulaUtils from '@/model/utils/AModelFmulaUtils';




/**
 *  角铝封板
 */
export default class AMNSPEntity {

     //模型构件
     static __create(data: AIBasicParams): GeometryReturnMeta<Array<any>> {
        let lcl = 0, lcw = 0, rcl = 0, rcw = 0; //左右切
        let lgl = +data.zyL, rgl = +data.yyL; //左右翼长
        let aw = +data.JLW, at = +data.bkT, ah = +data.JLH; //角铝参数
        let l = +data.H, w = +data.W - 2 * aw, t = +data.GMT;
        let mh = 15;  //角铝超出背板的固定高度

        let vec = [];
        let indices = [];

        let aa = this.__basicBoard(l + ah - mh, w, t, lcl, lcw, rcl, rcw, data);
        indices.push(...aa.indices.map((value) => { value += vec.length / 3; return value; }))
        vec.push(...aa.vertices);

        let bb = this.__aluCom(w, l, aw, ah, at, t, lgl, rgl, data);
        indices.push(...bb.indices.map((value) => { value += vec.length / 3; return value; }))
        vec.push(...bb.vertices);

        this.setDuan(data, w, l + ah - mh);

        return {
            vertices: vec,
            indices: indices,
            meshface: []
        }
    }


    private static setDuan(data: AIBasicParams, w, top) {
        data["duan"] = [
            0, data.H, +data.GMT,
            w, data.H, +data.GMT,
        ];
        data["zhong"] = {
            H: [
                {
                    pointer: [w / 2, top, 0],
                    center: [w / 2, top / 2, 0]
                }
            ],
            RH: [
                {
                    pointer: [w / 2, 0, 0],
                    center: [w / 2, top / 2, 0]
                }
            ],
            W: [
                {
                    pointer: [w, top / 2, 0],
                    center: [w / 2, top / 2, 0]
                },
            ],
            RW: [
                {
                    pointer: [0, top / 2, 0],
                    center: [w / 2, top / 2, 0]
                },
            ]
        }
    }



    /** 创建一个前后面带洞的板*/
    private static __createBoardWithHole(c: CreateMeta): GeometryReturnMeta<Array<any>> {
        let vec = [];
        let indics = [];
        let holePoints = [];
        let holePoints2 = [];
        let holeIndex = null;

        let holePath = AluGeoUtil.createHoleMeta(c.holeMeta);

        if (holePath.length > 0) {
            holeIndex = [];
            let curr = c.f.length / 3;
            for (let hole of holePath) {

                holeIndex.push(curr);

                let v2s = hole.getPoints(16);
                for (let v2 of v2s) {
                    holePoints.push(v2.x, v2.y, c.b[2]);
                    holePoints2.push(v2.x, v2.y, c.f[2]);
                }

                curr += v2s.length;
            }
        }


        //合并
        if (c.holeMeta && c.holeMeta.extra) {
            holeIndex = holeIndex ?? [];
            let curr = c.f.length / 3 + holePoints.length / 3;
            for (let item of c.holeMeta.extra) {

                holeIndex.push(curr);

                let bh = item[0];
                let fh = item[1];
                holePoints.push(...bh);
                holePoints2.push(...fh);

                curr += bh.length / 3;
            }
        }


        //前面
        let tp = c.f.concat(holePoints2);
        let ins = earcut(tp, holeIndex, 3)
        vec.push(...tp);
        indics.push(...ins);

        //背面
        tp = c.b.concat(holePoints);
        ins = earcut(tp, holeIndex, 3);
        ins = ins.reverse();
        indics.push(...ins.map((value) => { value += vec.length / 3; return value }));
        vec.push(...tp);

        let n = vec.length / 3;
        //侧面
        for (let i: number = 0, j: number = c.f.length - 3; i < c.f.length; i += 3) {
            // let j = i + 3;
            vec.push(c.f[i], c.f[i + 1], c.f[i + 2]);  //0
            vec.push(c.f[j], c.f[j + 1], c.f[j + 2]);  //1

            vec.push(c.b[i], c.b[i + 1], c.b[i + 2]);   //2
            vec.push(c.b[j], c.b[j + 1], c.b[j + 2]);   //3

            indics.push(n + 2, n, n + 1);
            indics.push(n + 1, n + 3, n + 2);

            j = i;
            n += 4;
        }


        return {
            vertices: vec,
            indices: indics,
            meshface: []
        }
    }


    /** 背板*/
    private static __basicBoard(l, w, t, lcl, lcw, rcl, rcw, data): GeometryReturnMeta<Array<any>> {
        // let fn = new NodeLink(null, null, null);

        //参数处理 左右切的点
        // let fl = [0, 0, 0];
        // if (lcl > 0 && lcw > 0) {
        //     fl = [];
        //     fl.push(0, lcl, 0);
        //     fl.push(lcw, lcl, 0);
        //     fl.push(lcw, 0, 0);
        // }

        // let f2 = [w, 0, 0];
        // if (rcl > 0 && rcw > 0) {
        //     f2 = [];
        //     f2.push(w - rcw, 0, 0);
        //     f2.push(w - rcw, rcl, 0);
        //     f2.push(w, rcl, 0);
        // }

        // let back = [];
        // back.push(...fl);
        // back.push(...f2);
        // back.push(w, l, 0);
        // back.push(0, l, 0);

        // let front = Array.from(back).map((value, index) => {
        //     if (index % 3 == 2) {
        //         value += t;
        //     }
        //     return value;
        // })


        //缺口参数
        let zqkwd = 0;
        let zqkgd = 0;
        let zqkwoff = 0;
        let zqkloff = 0;
        let yqkwd = 0;
        let yqkgd = 0;
        let yqkwoff = 0;
        let yqkloff = 0;


        /** 这里是用框架的  */
        let f = polygon([[
            [0, 0],
            [w, 0],
            [w, l],
            [0, l],
            [0, 0]
        ]])

        //左缺口的参数
        let p1 = polygon([
            [
                [zqkwoff, zqkloff],
                [zqkwoff + zqkwd, zqkloff],
                [zqkwoff + zqkwd, zqkloff + zqkgd],
                [zqkwoff, zqkloff + zqkgd],
                [zqkwoff, zqkloff],
            ]
        ])

        //右缺口参数
        let start = w - yqkwoff;
        let p2 = polygon([
            [
                [start, yqkloff],
                [start, yqkloff + yqkgd],
                [start - yqkwd, yqkloff + yqkgd],
                [start - yqkwd, yqkloff],
                [start, yqkloff],
            ]
        ])

        let r = difference(f, p1);
        let rr = difference(r.geometry, p2);

        // let face = [];
        let back = null;
        let front = null;
        let hole = [];
        let g = rr.geometry.coordinates;

        for (let i: number = 0; i < g.length; i++) {
            let b = [];
            let f = [];

            let gg = g[i];
            for (let j: number = 0; j < gg.length - 1; j++) {
                b.push(...gg[j], 0);
                f.push(...gg[j], t);
            }


            if (i == 0) {
                back = b;
                front = f;
            }
            else {
                hole.push([b, f]);
            }
        }


        let h = new HoleMeta(0, 0, null, "x", null, hole);
        let c: CreateMeta = new CreateMeta(t, front, back, h);
        return this.__createBoardWithHole(c);
    }

    /** 角铝块
     * tw 板宽
     * tl 板高
     * aw 角铝宽
     * ah 角铝高
     * at 角铝板厚
     * lal 
     * t 背板厚
     * lgl 左翼长
     * rgl 右翼长
    */
    private static __aluCom(tw, tl, aw, ah, at, t, lgl, rgl, data: AIBasicParams): GeometryReturnMeta<Array<any>> {

        let rs: GeometryReturnMeta<Array<any>> = { vertices: [], indices: [], meshface: [] };

        let h = this.__HAluCom(ah, tw, at, tl, t);
        rs.indices.push(...h.indices);
        rs.vertices.push(...h.vertices);

        let lc = this.__LAluCom(ah, aw, lgl, at, tl, t, data);
        rs.indices.push(...lc.indices.map((value) => { value += rs.vertices.length / 3; return value; }));
        rs.vertices.push(...lc.vertices);

        let rc = this.__RAluCom(ah, aw, rgl, at, tl, tw, t, data);
        rs.indices.push(...rc.indices.map((value) => { value += rs.vertices.length / 3; return value; }));
        rs.vertices.push(...rc.vertices);

        return rs;
    }

    /** 横角铝
     *  l == y
     *  w == x
     *  t == z
     *  dis 离板底高
    */
    private static __HAluCom(l, w, t, dis, zdis): GeometryReturnMeta<Array<any>> {
        let vec = [];
        let indics = [];

        let b = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0
        ];
        let f = [
            0, t, t, w, t, t, w, l, t, 0, l, t
        ];

        let c: CreateMeta = new CreateMeta(t, f, b, null);
        let re = this.__createBoardWithHole(c);
        vec.push(...re.vertices);
        indics.push(...re.indices);

        b = [
            0, t, -t, w, t, -t, w, l, -t, 0, l, -t
        ]

        f = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0
        ];

        c = new CreateMeta(t, f, b, null);
        re = this.__createBoardWithHole(c);

        //绕x旋转90度
        let xr = 0.5 * Math.PI;
        let sr = Math.sin(xr);
        let cr = Math.cos(xr);
        for (let i: number = 0; i < re.vertices.length; i += 3) {
            let y = re.vertices[i + 1];
            let z = re.vertices[i + 2];

            re.vertices[i + 1] = y * cr - sr * z;
            re.vertices[i + 2] = sr * y + z * cr;
        }

        indics.push(...re.indices.map((value) => { value += vec.length / 3; return value; }))
        vec.push(...re.vertices);


        for (let i: number = 0; i < vec.length; i += 3) {
            vec[i + 2] += zdis;
            vec[i + 1] += dis;
        }


        return {
            vertices: vec,
            indices: indics,
            meshface: []
        }
    }
    /** 左翼
     *  al == 垂直向高
     *  al1 == xoz向高
     *  law == 左翼长
     *  raw == 右翼长
     *  at == 板厚
     *  
     * 
    */
    private static __LAluCom(al, al1, aw, at, dis, zdis, data: AIBasicParams): GeometryReturnMeta<Array<any>> {

        let h = new HoleMeta((+data.BKDia) * 0.5, al1 - (+data.fjcmjl), AModelFmulaUtils.getHolesbyExpress(data["p_zkkw"], aw,2,data,'p_zkkw',10002), "x");
        let result = this.__wingCom(al, al1, aw, at, h);

        //绕y旋转90度
        let yr = -0.5 * Math.PI;
        let ysr = Math.sin(yr);
        let ycr = Math.cos(yr);
        for (let i: number = 0; i < result.vertices.length; i += 3) {
            let x = result.vertices[i];
            let z = result.vertices[i + 2];

            result.vertices[i] = x * ycr + ysr * z;
            result.vertices[i + 1] += dis;
            result.vertices[i + 2] = ycr * z - x * ysr + zdis;
        }

        return result;
    }

    /** 右翼*/
    private static __RAluCom(al, al1, aw, at, dis, xdis, zdis, data: AIBasicParams): GeometryReturnMeta<Array<any>> {

        //挖孔需要反向
        let h = new HoleMeta((+data.BKDia) * 0.5, al1 - (+data.fjcmjl), AModelFmulaUtils.getHolesbyExpress(data["p_ykkw"], aw,2,data,'p_ykkw',10002).map((value) => { value = aw - value; return value }), "x");
        let result = this.__wingCom(al, al1, aw, at, h);

        //绕y旋转90度
        let yr = 0.5 * Math.PI;
        let ysr = Math.sin(yr);
        let ycr = Math.cos(yr);
        for (let i: number = 0; i < result.vertices.length; i += 3) {
            let x = result.vertices[i];
            let z = result.vertices[i + 2];

            result.vertices[i] = x * ycr + ysr * z + xdis;
            result.vertices[i + 1] += dis;
            result.vertices[i + 2] = ycr * z - x * ysr + zdis + aw;
        }

        return result;
    }


    /** 翼未加工部件*/
    private static __wingCom(al, al1, aw, at, holeMeta: HoleMeta): GeometryReturnMeta<Array<any>> {
        let vec = [];
        let indics = [];

        let b = [
            0, 0, 0, aw, 0, 0, aw, al, 0, 0, al, 0
        ];
        let f = [
            0, at, at, aw, at, at, aw, al, at, 0, al, at
        ];

        let a: CreateMeta = new CreateMeta(at, f, b, null);
        let re = this.__createBoardWithHole(a);
        vec.push(...re.vertices);
        indics.push(...re.indices);

        b = [
            0, at, -at, aw, at, -at, aw, al1, -at, 0, al1, -at
        ]

        f = [
            0, 0, 0, aw, 0, 0, aw, al1, 0, 0, al1, 0
        ]

        let c: CreateMeta = new CreateMeta(at, f, b, holeMeta);
        re = this.__createBoardWithHole(c);

        //绕x旋转90度
        let xr = 0.5 * Math.PI;
        let sr = Math.sin(xr);
        let cr = Math.cos(xr);
        for (let i: number = 0; i < re.vertices.length; i += 3) {
            let y = re.vertices[i + 1];
            let z = re.vertices[i + 2];

            re.vertices[i + 1] = y * cr - sr * z;
            re.vertices[i + 2] = sr * y + z * cr;
        }

        indics.push(...re.indices.map((value) => { value += vec.length / 3; return value; }))
        vec.push(...re.vertices);

        return {
            vertices: vec,
            indices: indics,
            meshface: []
        }
    }


}

